package com.gwz.cardserver.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gwz.cardserver.dto.ReqBase;
import com.gwz.cardserver.dto.ResBase;
import com.gwz.cardserver.dto.account.AccountDto;
import com.gwz.cardserver.entity.Account;
import com.gwz.cardserver.global.GlobalCache;
import com.gwz.cardserver.mapper.AccountMapper;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

@Service
public class AccountService extends ServiceImpl<AccountMapper, Account> {
    @Autowired
    private GlobalCache globalCache;

    /**
     * 登录
     *
     * @param accountDto
     * @return
     */
    public String login(AccountDto accountDto, ChannelHandlerContext ctx, ReqBase reqBase) {
        Account user = lambdaQuery().eq(Account::getAccount, accountDto.getAccount()).one();
        Assert.notNull(user, ResBase.fall(reqBase, "此用户不存在"));
        Assert.isTrue(user.getPassword().equals(accountDto.getPassword()), ResBase.fall(reqBase, "密码错误"));
        Assert.isTrue(!isOnline(user.getId()), ResBase.fall(reqBase, "账号已登录"));
        online(user.getId(), ctx);
        return user.getId();
    }

    /**
     * 注册
     *
     * @param accountDto
     * @return
     */
    public String regist(AccountDto accountDto, ChannelHandlerContext ctx, ReqBase reqBase) {
        Integer userCount = lambdaQuery().eq(Account::getAccount, accountDto.getAccount()).count();
        Assert.isTrue(userCount == 0, ResBase.fall(reqBase, "此用户已存在"));
        Account account = new Account();
        account.setAccount(accountDto.getAccount());
        account.setPassword(accountDto.getPassword());
        account.setLv(1);
        account.setBeen(0);
        account.setLoseCount(0);
        account.setRunCount(0);
        account.setWinCount(0);
        account.setExp(0);
        save(account);
        online(account.getId(), ctx);
        return account.getId();
    }

    public Account getById(ChannelHandlerContext ctx) {
        String accountId = get(ctx);
        Account account = getById(accountId);
        return account;
    }

    /**
     * 判断是否在线
     *
     * @param accountId
     * @return
     */
    public boolean isOnline(String accountId) {
        ChannelHandlerContext channelHandlerContext = globalCache.getAccountStringMap().get(accountId);
        if (channelHandlerContext == null) {
            return false;
        }
        if (channelHandlerContext.isRemoved()) {
            return false;
        }
        channelHandlerContext.isRemoved();
        return true;
    }

    /**
     * 判断是否在线
     *
     * @param channelHandlerContext
     * @return
     */
    public boolean isOnline(ChannelHandlerContext channelHandlerContext) {
        if(channelHandlerContext.isRemoved()){
            return false;
        }
        return globalCache.getAccountChannelContextMap().containsKey(channelHandlerContext);
    }

    /**
     * 上线
     *
     * @param accountId
     * @param channelHandlerContext
     */
    public void online(String accountId, ChannelHandlerContext channelHandlerContext) {
        globalCache.addAccount(accountId, channelHandlerContext);
    }

    /**
     * 下线
     *
     * @param channelHandlerContext
     */
    public void offline(ChannelHandlerContext channelHandlerContext) {
        globalCache.removeAccount(channelHandlerContext);

    }

    /**
     * 下线
     *
     * @param accountId
     */
    public void offline(String accountId) {
        globalCache.removeAccount(accountId);
    }

    /**
     * 获取在线玩家id
     *
     * @param channelHandlerContext
     */
    public String get(ChannelHandlerContext channelHandlerContext) {
        return globalCache.getAccountChannelContextMap().get(channelHandlerContext);
    }

    public void setName(String nickName, ChannelHandlerContext ctx) {
        String accountId = get(ctx);
        lambdaUpdate().set(Account::getNickName, nickName).eq(Account::getId, accountId).update();
    }


    public void removeUserByChannel(ChannelHandlerContext channelHandlerContext) {
        offline(channelHandlerContext);
        System.out.printf("s");
    }
}
